package com.shilun.springboot.hello_demo.aop;

import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
@Component
public class WebLogAspect {
	private Logger logger = Logger.getLogger(getClass());
	
	@Pointcut("execution(public * com.shilun.springboot.hello_demo.controller..*.*(..))")
	public void webLog() {
		
	}
	
	@Before("webLog()")
	public void doBefore(JoinPoint joinPoint) throws Throwable {
		// 接收到请求，记录请求内容
		ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = requestAttributes.getRequest();
		logger.info("#####################请求开始####################");
		logger.info("URL : " + request.getRequestURL().toString());
		logger.info("HTTP_METHOD : " + request.getMethod());
		logger.info("IP : " + request.getRemoteAddr());
		Enumeration<String> parameterNames = request.getParameterNames();
		while (parameterNames.hasMoreElements()) {
			String name = (String) parameterNames.nextElement();
			logger.info("name:{" + name + "},value:{" + request.getParameter(name) + "}");
		}
	}
	
	@AfterReturning(returning="ret",pointcut="webLog()")
	public void doAfterReturning(JoinPoint joinPoint,Object ret) throws Throwable {
		// 处理完请求，返回内容
		logger.info("RESPONSE : " + ret);
		logger.info("#####################请求结束####################");
	}
	
	//@Around(value="webLog()")
	public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		Object result=null;
		try{
			return proceedingJoinPoint.proceed();
		}catch(Exception exception) {
			if( exception instanceof java.lang.ArithmeticException){
				result="出现了内部计算错误";
			}else{
				result="出现了其他未知错误";
			}
			logger.error(result,exception);
		}
		return result;
	}
	
	@AfterThrowing(throwing="e",pointcut="webLog()")
	public void afterThrowing(JoinPoint joinPoint,Exception e) throws Throwable{
		Object result=null;
		if( e instanceof java.lang.ArithmeticException){
			result="出现了内部计算错误";
		}else{
			result="出现了其他未知错误";
		}
		logger.error(result,e);
	}
}
